SERVEI DE LLISTATS









 Introducció

Propòsit

El servei de llistats permet la presentació de llistats HTML en el que es permet a l'usuari:

  1. Ordenar per columna de manera ascendent o descendent.
  2. Paginació dels resultats i navegació per pàgines mitjançant "avanç" i "retrocés" (primera, última, següent, anterior), i per accés directe a un número de pàgina.
  3. Presentar un número determinat de resultats per pàgina.
  4. Acotar el número màxim de resultats a mostrar.

A més, proporciona ajut a l'usuari, presentant:

  1. Rollover de la fila al passar el ratolí per sobre.
  2. Desactivació dels botons de navegació depenent de la pàgina en la que s'estigui ubicat.
  3. Indicació de la columna per la que s'està ordenant mitjançant icones, mostrant si és ascendent o descendent.
  4. Look & feel configurable.

Context i Escenaris d'Ús

El servei de llistats es troba dins dels serveis de Propòsit General de canigo.

Versions i Dependències

En el present apartat es mostren quines són les versions i dependències necessàries per fer ús del Servei.

Dependències Bàsiques

Les dependències descrites a la següent url son requerides per tal de fer funcionar el servei:
Dependències Servei de Llistats

A qui va dirigit

Aquest document va dirigit als següents perfils:

  1. Programador. Per conéixer l'ús del servei
  2. Arquitecte. Per conéixer quins són els components i la configuració del servei
  3. Administrador. Per conéixer cóm configurar el servei en cadascun dels entorns en cas de necessitat

Documents i Fonts de Referència

[1] Value List http://valuelist.sourceforge.net/overview.html
[2] Hibernate http://www.hibernate.org
[3] Jakarta POI http://jakarta.apache.org/poi/
[4] iText http://www.lowagie.com/iText/

Glossari

Log4J
Un dels framework de traces més extés. Es basa en l'ús de Appenders, Categories i Layouts. Veure l'annex per a més informació.

Value List
Llibrería de tags que ens permet la definició, execució i presentació de queries contra una base de dades

Jakarta POI
Llibreria que ens permet la generació de documents en format (principalment) Microsoft Word i Microsoft Excel

iText
Llibreria que ens permet la generació de fitxers PDF 'al vol', és a dir, sense cap plantilla predefinida sinó mitjançant la programació

Hibernate
Llibreria de persistència de gran rendiment, que permet desenvolupar les classes persistents amb un idioma orientat a objectes.

Descripció Detallada

Arquitectura i Components

Existeixen tres tipus de components. Podem classificar-los en:

  1. Interfícies i components genèrics.
  2. Implementació de les interfícies.
  3. Llibrería de tags per a la presentació de resultats.

Es pot trobar tota la documentació JavaDoc y el codi font referent aquests components a les següents urls:

JavaDoc: http://canigo.ctti.gencat.net/confluence/canigodocs/site/canigo2_0/canigo-services-web/apidocs/index.html
Codi Font:  http://canigo.ctti.gencat.net/confluence/canigodocs/site/canigo2_0/canigo-services-web/xref/index.html

Llibreria de tags

Els tags que s'utilitzen són els propis de la llibreria Value List.

<vlh:root/>
Aquest tag és obligatori com a element pare per la resta de tags

Atribut Descripció
value Nom de la variable on es troben les dades (típicament "list").
url L'URL base per realitzar els posts a un action. Tots els links generats a la taula de resultats es muntaran a partir d'aquest atribut.
includeParameters (opcional) Atribut en el que inclourem sempre el "reqCode" i la resta de paràmetres pels que ha pogut haver estat filtrat en el Value List. Els paràmetres es separen mitjançant el caràcter pipe "|".
configName Nom del bean de configuració (típicament vlConfig).

<vlh:retreive/>
Aquest tag és opcional ja que la informació ve implícita segons l'Action executat. S'utilitza si per una vista en concret es vol utilitzar un altre Value List del definit per defecte.

Atribut Descripció
name Nom de del adaptador que retorna les dades.

<vlh: Pagging/>
Tag que genera el panell per controlar la paginació dels resultats i navegació per pàgines mitjançant "avanç" i "retrocés" (primera, última, següent, anterior), i per accés directe a un número de pàgina.

Important
Aquest tag requereix per a que funcioni correctament, que en el fitxer referenciat com a "messageResource" s'especifiquin les següents "keys":

paging.text.totalRow={0} Total
paging.text.pageFromTotal= <b>{0}</b> of {1} page(s)
paging.first(off)=<img src="images/first(off).gif">
paging.first(on)=<img src="images/first(on).gif">
paging.previous(off)=<img src="images/previous(off).gif">
paging.previous(on)=<img src="images/previous(on).gif">
paging.forward(off)=<img src="images/forward(off).gif">
paging.forward(on)=<img src="images/forward(on).gif">
paging.last(off)=<img src="images/last(off).gif">
paging.last(on)=<img src="images/last(on).gif">
paging.delim=
paging.focus(on)=<img src="images/focus(on).gif">
paging.focus(off)=<img src="images/focus(off).gif">
paging.focus(disabled)=<img src="images/focus(disabled).gif">
paging.focus(error)=<img src="images/focus(error).gif">





<vlh:row/>
La funció d'aquest tag és la d'iteració dels resultats.

Atribut Descripció
bean Nom de la clau del PageContext on es troben les dades (típicament "job").
display (opcional) Nom de del adaptador que retorna les dades (en el cas de que s'utilitzi l'adaptador per defecte de l'action tindrà el valor "<%=(String)request.getAttribute("subReqCode")%>").

<vlh:attribute/>
Aquest tag afegeix al tag pare atributs HTML.

Atribut Descripció
name Nom de l'atribut HTML
value Valor de l'atribut HTML

<vlh:column/>
Aquest tag renderitza una columna per cada registre iterat.

Atribut Descripció
property Nom de la propietat a mostrar. Les associacions amb altres taules es poden definir de manera implícita de la manera: "property="productid.id""
sortable (opcional) Defineix si el resultat està ordenat per aquest camp i amb quin ordre ("asc": ascendent, "desc": descendent). En el cas de no incloure aquest atribut no es podra ordenar els resultats per aquesta columna.
titleKey Nom de la columna definit en el "message resources".

<vlh:controls/>
Aquest tag renderitza una columna per incloure controls sobre cada registre (eliminar, modificar, etc.)

Atribut Descripció
titlekey Nom de la columna definit en el "message resources".

<vlh:action/>
Aquest tag defineix una URL per realitzar addicionals post per diferents actions segons el que es vulgui realitzar.

Atribut Descripció
url (opcional) Si no s'inclou s'utilitza l'URL del tag "root".

Nota
És pot definir una URL que retorni la vista del resultat en format PDF.
Exemple:

<vlh:action  url="categories.do?">

<vlh:addParam name="reqCode"  value="searchExportPDF" temp="false"/>

<bean:message  key="valueListInfo.toPDF"/>

</vlh:action>





<vlh:addParam/>
Aquest tag afegeix paràmetres al tag pare (típicament "root" o "action").

Atribut Descripció
name Nom del paràmetre a afegir a l'URL.
property (opcional) Valor dinàmic obtingut d'una propietat del registre.
value (optional) Valor estàtic pel paràmetre.
temp (true/false) Afegeix el prefix "ACTION_TEMP_PARAM" al nom del paràmetre.

Instal- lació i Configuració

Instal- lació

La instal- lació del servei requereix de la utilització de la llibreria 'canigo-services-web-lists' i les dependències indicades a l'apartat 'Introducció-Versions i Dependències'.

Configuració

La configuració del servei implica:

  1. Definir el servei i injectar-li les seves dependències
  2. Enllaç d'una acció amb el seu "Value List"

Definició del servei i de les seves dependències

Fitxer de configuració: canigo-services-web-lists.xml

Ubicació proposada: <PROJECT_ROOT>/src/main/resources/spring

La definició del servei requereix configurar un bean "pare" amb un identificador i els següents atributs:

Atributs:

Atribut Requerit Descripció
class Implementació concreta del servei a utilitzar

Opcions:
# net.gencat.ctti.canigo.services.web.lists.impl.SimpleValueListActionHelper.

També es necessari configurar les següents propietats:

Propietat Requerit Descripció
valueListHelper Classe d'ajuda per a les búsquedes
maxExportRows No Número màxim de files a exportar
logService Referència al servei de traces

Exemple:

...

<bean  name="valueListActionHelper"

class="net.gencat.ctti.canigo.services.web.lists.impl.SimpleValueListActionHelper">

<property  name="valueListHelper">

<ref bean="valueListHelper"  />

</property>

<property name="maxExportRows"  value="2"></property>

<property name="logService"  ref="loggingService"/>

</bean>

...





Fitxer de configuració: canigo-services-web-lists.xml

Ubicació proposada: <PROJECT_ROOT>/src/main/resources/spring

La definició del servei requereix configurar un bean "simplificador" per a executar les búsquedes:

Atributs:

Atribut Requerit Descripció
class Classe d'ajuda a utilitzar

Opcions:
# net.mlw.vlh.web.mvc.ValueListHandlerHelper

També es necessari configurar les següents propietats:

Propietat Requerit Descripció
valueListHandler Delegat de les búsquedes

Exemple:

...

<bean  id="valueListHelper"

class="net.mlw.vlh.web.mvc.ValueListHandlerHelper">

<property  name="valueListHandler">

<ref bean="valueListHandler"  />

</property>

</bean>

...






Fitxer de configuració: canigo-services-web-lists.xml

Ubicació proposada: <PROJECT_ROOT>/src/main/resources/spring

La definició del servei requereix configurar un bean "delegat" per a localitzar les búsquedes:

Atributs:

Atribut Requerit Descripció
class Classe delegada a utilitzar

Opcions:
# net.mlw.vlh.DefaultValueListHandlerImpl

També es necessari configurar les següents propietats:

Propietat Requerit Descripció
config.adapters Mapa que conté els identificadors de cada una de les búsquedes a utilitzar i els beans que es cridaran per a fer les búsquedes.

Exemple:

...

<bean  name="valueListHandler"

class="net.mlw.vlh.DefaultValueListHandlerImpl">

<property  name="config.adapters">

<map>

<entry  key="productList">

<bean  parent="baseHibernateAdapter">

<property  name="hql">

<value>

FROM

net.gencat.ctti.canigo.samples.jpetstore.model.Product

AS  vo WHERE 1=1

/~name: AND vo.name LIKE \{name\} ~/

/~category: AND  vo.category.id LIKE \{category\} ~/

/sortColumn: ORDER BY vo.[sortColumn]  [sortDirection]/

</value>

</property>

</bean>

</entry>

</map>

</property>

</bean>

...






Fitxer de configuració: canigo-services-web-lists.xml

Ubicació proposada: <PROJECT_ROOT>/src/main/resources/spring

La definició del servei requereix configurar un bean "delegat" per a executar les búsquedes:

Atributs:

Atribut Requerit Descripció
class Classe delegada a utilitzar

Opcions:
# net.mlw.vlh.adapter.hibernate3.Hibernate30Adapter

També es necessari configurar les següents propietats:

Propietat Requerit Descripció
sessionFactory Si Referència a la factoria de sessions d'Hibernate
defaultNumberPerPage Si Número de resultats per defecte de les pàgines
defaultSortColumn Si Columna d'ordenació per defecte
defaultSortDirection Si Direcció d'ordenació per defecte
removeEmptyString Si Elimina els valors buits dels filtres de la búsqueda

Exemple:

...

<bean  name="baseHibernateAdapter"

class="net.mlw.vlh.adapter.hibernate3.Hibernate30Adapter">

<property  name="sessionFactory" ref="sessionFactory"/>

<property  name="defaultNumberPerPage" value="5"/>

<property  name="defaultSortColumn" value="id"/>

<property  name="defaultSortDirection" value="asc"/>

<property  name="removeEmptyStrings" value="true"/>

</bean>

...






Fitxer de configuració: canigo-services-web-lists.xml

Ubicació proposada: <PROJECT_ROOT>/src/main/resources/spring

La definició del servei requereix configurar un bean "configurador" per a la presentació de resultats:

Atributs:

Atribut Requerit Descripció
class Classe configuradora a utilitzar

Opcions:
# net.mlw.vlh.web.ValueListConfigBean

També es necessari configurar les següents propietats:

Propietat Requerit Descripció
messageSource Si Referència al servei multi idioma
displayProviders Si Proveïdors dels diferents tipus de llistats. Opcions:
# net.gencat.ctti.canigo.services.web.vlh.tag.support.PdfDisplayProvider
# net.gencat.ctti.canigo.services.web.vlh.tag.support.ExcelDisplayProvider

Exemple:

...

<bean name="vlConfig"  class="net.mlw.vlh.web.ValueListConfigBean"

singleton="false">

<property  name="messageSource" ref="messageSource"/>

<property  name="displayProviders">

<map>

<entry  key="ExportPDF">

<bean  class="net.gencat.ctti.canigo.services.web.vlh.tag.support.PdfDisplayProvider"  singleton="false">

<property name="logService"  ref="loggingService"/>

<property name="i18nService"  ref="i18nService"/>

<property  name="skipColumns">

<list>

<value>jsp.categories.categoryList.actions</value>

<value>jsp.products.productList.actions</value>

</list>

</property>

</bean>

</entry>

</map>

</property>

</bean>

...




Enllaç d'una acció amb el seu "Value List"

Fitxer de configuració: action-servlet-XXX.xml

Ubicació proposada: <PROJECT_ROOT>/src/main/resources/spring

Cada acció que implementi una búsqueda necessita la definició d'un bean que hereti del bean "pare" del servei i que tingui els següents atributs:

Atributs:

Atribut Requerit Descripció
listName Nom de la consulta que es llençarà
tableId Identificador únic de la taula que es consulta, per a guardar en sessió els filtres de les búsquedes

Exemple:

...

<property name="valueListActionHelper">

<bean  parent="valueListActionHelper">

<property  name="listName">

<value>categoriesList</value>

</property>

<property  name="tableId"  value="CATEGORY"/>

</bean>

</property>

...





Utilització del servei

Per a poder utilitzar el servei, s'han de seguir els següents passos:

  • Implementar la interfície 'UsesValueList':
    public class CategoryAction extends DispatchActionSupport implements UsesValueList {
        ...
    }



  • Definir un attribut d'instància que implementi 'ValueListActionHelper'
    private ValueListActionHelper valueListActionHelper;



  • Definir els 'setters' i 'getters' corresponents
    public ValueListActionHelper getValueListActionHelper() {
        return valueListActionHelper;
    }
    public void setValueListActionHelper(ValueListActionHelper valueListActionHelper) {
        this.valueListActionHelper = valueListActionHelper;
    }



  • Implementar els mètodes de búsqueda corresponents
    public ActionForward search(ActionMapping mapping, ActionForm form,
    javax.servlet.http.HttpServletRequest request,javax.servlet.http.HttpServletResponse response)
        throws Exception {
            valueListActionHelper.search(mapping, form, request, response);
            return mapping.findForward("list");
        }



  • Crear els JSP's amb els tags necessaris per a presentar els resultats

Integració amb altres serveis

Servei multi idioma

El servei de llistats s'integra amb el servei de multi idioma a partir de la propietat "messageSource" del bean "configurador" (típicament "vlConfig"). És necessari per això definir la configuració que s'utilitzarà (atribut "configName") en cadascun dels JSP de presentació de resultats

Servei de persistència

El servei de llistats s'integra amb el servei de persistència a partir de la propietat "sessionFactory" del bean "delegat" (típicament "baseHibernateAdapter") d'executar les queries.

Preguntes Freqüènts

Per què el servei de llistats no em mostra els títols de les columnes?
Per a mostrar els "titleKey" corresponents en el servei de llistats és necessari configurar al bean "configurador" (típicament vlConfig) la referència al servei multi idioma (propietat "messageSource") i afegir als JSP el atribut "configName" al tag <vlh:root/>

Exemples

Com exemple d'utilització del servei de llistats s'inclou el resultat d'un llistat i el codi font de la vista i la seva Action.

public class CategoryAction extends DispatchActionSupport implements
        UsesValueList {
    private ValueListActionHelper valueListActionHelper;

...

    public ValueListActionHelper getValueListActionHelper() {
        return valueListActionHelper;
    }

    public void setValueListActionHelper(ValueListActionHelper valueListActionHelper) {
        this.valueListActionHelper = valueListActionHelper;
    }
...
}





Codi 1 Exemple d'utilització del servei associat a una 'Action'
<%@ include file="layouts/fwkTagLibs.jsp"%>

<fwk:html>

<!-- Search criteria -->
<table cellpadding="0" cellspacing="0" border="0">
  <tr>
    <td width="100%" align="center">
      <fwk:form action="/categories.do" reqCode="search" style="height: 50px; width:100%;" >
        <fwk:text property="id" key="category.id" mode="E,E,E" size="4" maxlength="4"
        styleClass="LABEL" />
        <fwk:text property="descn" key="category.descn" mode="E,E,E" size="40" maxlength="40"
        styleClass="LABEL" />
        <layout:image styleClass="submit(reqCode:'search',message:'submit.button.search')"
        src="images/ast.gif"/>
      </fwk:form>
    </td>
  </tr>
</table>

<!-- Result list -->
<logic:present name="list" scope="request">
  <vlh:root value="list" url="categories.do?" includeParameters="reqCode|id|descn"
  configName="vlConfig">
    <table width="450">
    <!-- pagination section -->
      <tr>
          <td align="left" nowrap="true">
           <c:out     value="${list.valueListInfo.totalNumberOfEntries}"/>
           <bean:message key="valueListInfo.totalNumberOfEntries"/>
        (<c:out value="${list.valueListInfo.pagingPage}" />
           <bean:message key="valueListInfo.totalNumberOfEntries.of"/>
           <c:out value="${list.valueListInfo.totalNumberOfPages}"/>)
         </td>
          <td align="right">
           <vlh:paging/>
         </td>
      </tr>
    <!-- end of Pagination -->

        <tr>
        <td colspan="2">
          <table width="450" class="classicLook" cellspacing="0"
                 cellpadding="0">
            <vlh:row bean="job"
              display="<%=(String)request.getAttribute("subReqCode")%>">
              <vlh:attribute name="onmouseover">
            this.className='selected';
              </vlh:attribute>
              <vlh:attribute name="onmouseout">
            this.className='zebra0';
              </vlh:attribute>
              <vlh:column titleKey="category.id" property="id"
                sortable="desc" />
              <vlh:column titleKey="category.name" property="name"
                sortable="desc" />
              <vlh:controls titleKey="category.control">
                <vlh:action url="products.do?">
            <vlh:addParam name="reqCode" value="search"
                    temp="false" />
                   <bean:message key="products.edit"/>
                  <vlh:addParam name="category" property="id"
                    temp="false" />
                </vlh:action>
                <vlh:action url="categories.do?">
                  <vlh:addParam name="reqCode" value="edit"
                    temp="false"/>
                   <bean:message key="category.edit"/>
                  <vlh:addParam name="id" property="id" temp="false" />
                </vlh:action>
              </vlh:controls>
            </vlh:row>
          </table>
        </td>
      </tr>
    </table>

    <vlh:action url="categories.do?">
      <vlh:addParam name="reqCode" value="searchExportPDF" temp="false"/>
      <bean:message key="valueListInfo.toPDF"/>
    </vlh:action>
  </vlh:root>
</logic:present>

</fwk:html>





Codi 2 Exemple d'utilització del servei des d'una vista JSPNota
És important d'adonar-se'n com s'ha accedit a diferents propietats de la llistat (com el nombre de files, etc) a la "Pagination section".
Exemple:
<c:out  value="$\{list.valueListInfo.totalNumberOfEntries\}"/>